
/*
    Copyright 2010 Nathaniel Fairfield <than@timbrel.org>

    This file is part of Ravec.

    Ravec is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Ravec is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Ravec.  If not, see <http://www.gnu.org/licenses/>.
*/

// The HashGrid implements a sparse 3D map stored as a
// hash_map with HashKey computed from the coordinates.

#ifndef _RAVEC_HASH_GRID_H_
#define _RAVEC_HASH_GRID_H_

#include "b3d_grid.h"
#include <ext/hash_map>

namespace ravec {

template<typename T>
class HashGrid : public B3DGrid<T> {
 public:

  typedef __gnu_cxx::hash_map<int, T> GridMap;

  HashGrid(int size_x, int size_y, int size_z, T initial_value)
    : B3DGrid<T>(size_x, size_y, size_z, initial_value) {
  }

  ~HashGrid() {
  }

  int HashKey(int x, int y, int z) const {
    return (x * Grid<T>::size_y_ + y) * Grid<T>::size_z_ + z;   
  }

  // Basic accessors.
  T Get(int x, int y, int z) const {
    typename GridMap::const_iterator cit = map_.find(HashKey(x, y, z));
    if (cit == map_.end()) {
      return Grid<T>::initial_value_;
    } else {
      return cit->second;
    }
  }

  T Set(int x, int y, int z, T value) {
    return map_[HashKey(x, y, z)] = value;
  }

 protected:
  // Hash map that stores the grid cell values.
  GridMap map_;

};

}  // namespace ravec

#endif  // _RAVEC_HASH_GRID_H_
